package org.compiere.model;

import java.io.File;
import java.math.BigDecimal;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;

import org.compiere.apps.IProcessParameter;
import org.compiere.apps.ProcessCtl;
import org.compiere.apps.ProcessParameterPanel;
import org.compiere.apps.Waiting;
import org.compiere.process.DocAction;
import org.compiere.process.DocumentEngine;
import org.compiere.process.ProcessInfo;
import org.compiere.process.ProcessInfoParameter;
import org.compiere.util.ASyncProcess;
import org.compiere.util.CCache;
import org.compiere.util.CLogger;
import org.compiere.util.DB;
import org.compiere.util.Env;

public class Mhrmmaterialaid extends X_hrm_materialaid implements DocAction, ASyncProcess{

	/**
	 * 
	 */
	private static final long serialVersionUID = -9109326785677970505L;	
	
	private int AD_Process_ID;
	/**/
	ASyncProcess m_parent;
	
	/**	Static Logger	*/
	private static CLogger	s_log	= CLogger.getCLogger (Mhrmmaterialaid.class);

	public Mhrmmaterialaid(Properties ctx) {
		super(ctx);
	}

	public Mhrmmaterialaid(Properties ctx, int hrm_materialaid_ID,
			String trxName) {
		super(ctx, hrm_materialaid_ID, trxName);
	}
	
	public Mhrmmaterialaid(Properties ctx, ResultSet rs, String trxName) {
		super(ctx, rs, trxName);
	}	
	
	/**	Bonus Lines	*/
	private Mhrmmaterialaidline[] m_lines;
	private X_hrm_materialaidline[] m_linesacct;

	/**
	 * 	Get HR Materialaid Lines
	 * 	@param whereClause starting with AND
	 * 	@return lines
	 */
	private Mhrmmaterialaidline[] getLinesAid (String whereClause)
	{
		String whereClauseFinal = "hrm_materialaid_ID=? ";
		if (whereClause != null)
			whereClauseFinal += whereClause;
		List<Mhrmmaterialaidline> list = new Query(getCtx(), I_hrm_materialaid_line.Table_Name, whereClauseFinal, get_TrxName())
										.setParameters(gethrm_materialaid_ID())
										.list();
		return list.toArray(new Mhrmmaterialaidline[list.size()]);
	}	//	getLines

	/**
	 * 	Get Materialaid Lines
	 * 	@param requery
	 * 	@return lines
	 */
	public Mhrmmaterialaidline[] getLinesAid (boolean requery)
	{
		if (m_lines == null || m_lines.length == 0 || requery)
			m_lines = getLinesAid(null);
		set_TrxName(m_lines, get_TrxName());
		return m_lines;
	}	//	getLines

	/**
	 * 	Get Materialaid line
	 * 	@return lines
	 */
	public Mhrmmaterialaidline[] getLinesAid()
	{
		return getLinesAid(false);
	}	//	getLines
	
//	 X_hrm_materialaidline {
	/**
	 * 	Get HR Materialaid Lines
	 * 	@param whereClause starting with AND
	 * 	@return lines
	 */
	private X_hrm_materialaidline[] getLinesAidAcct (String whereClause)
	{
		String whereClauseFinal = "hrm_materialaid_ID=? ";
		if (whereClause != null)
			whereClauseFinal += whereClause;
		List<X_hrm_materialaidline> list = new Query(getCtx(), I_hrm_materialaidline.Table_Name, whereClauseFinal, get_TrxName())
										.setParameters(gethrm_materialaid_ID())
										.list();
		return list.toArray(new X_hrm_materialaidline[list.size()]);
	}	//	getLines

	/**
	 * 	Get Materialaid Lines
	 * 	@param requery
	 * 	@return lines
	 */
	public X_hrm_materialaidline[] getLinesAidAcct (boolean requery)
	{
		if (m_linesacct == null || m_linesacct.length == 0 || requery)
			m_linesacct = getLinesAidAcct(null);
		set_TrxName(m_linesacct, get_TrxName());
		return m_linesacct;
	}	//	getLines

	/**
	 * 	Get Materialaid line
	 * 	@return lines
	 */

	public X_hrm_materialaidline[] getLinesAidAcct()
	{
		return getLinesAidAcct(false);
	}	//	getLines
	
	public X_hrm_materialaidline getAidLine(int hrm_reservesectional_id) {
		X_hrm_materialaidline result = null;
		getLinesAidAcct();
		for(X_hrm_materialaidline l:m_linesacct) {
			if (l.gethrm_reservesectional_ID() ==  hrm_reservesectional_id) {
				result = l;
				break;
			}
		}
		return result;
	}
	
//	 } X_hrm_materialaidline 
/// DocAction
	
	/**	Process Message 			*/
	private String		m_processMsg = null;
	/**	Just Prepared Flag			*/
	private boolean		m_justPrepared = false;
	private Waiting m_waiting;
	
	
	public boolean processIt(String processAction) //throws Exception 
	{
		m_processMsg = null;
		DocumentEngine engine = new DocumentEngine (this, getDocStatus());
		return engine.processIt (processAction, getDocAction());
	}	//	process
	
	public boolean unlockIt() {
		// TODO Auto-generated method stub
		return false;
	}
	
	public boolean invalidateIt() {
		// TODO Auto-generated method stub
		return false;
	}
	
	public String prepareIt() {
		log.info(toString());
		m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_PREPARE);
		if (m_processMsg != null)
			return DocAction.STATUS_Invalid;

		//	Convert/Check DocType
		if (getC_DocType_ID() == 0)
		{
			m_processMsg = "No Document Type";
			return DocAction.STATUS_Invalid;
		}
		
		m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_AFTER_PREPARE);
		if (m_processMsg != null)
			return DocAction.STATUS_Invalid;

		//	Add up Amounts
		m_justPrepared = true;
		if (!DOCACTION_Complete.equals(getDocAction()))
			setDocAction(DOCACTION_Complete);
		return DocAction.STATUS_InProgress;
	}	//	prepareIt	
	
	public boolean approveIt() {
		log.info(toString());
		setIsApproved(true);
		return true;
	}

	@Override
	public boolean rejectIt() {
		// TODO Auto-generated method stub
		return false;
	}

	protected void getAD_Process_ID() {
		
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		// 
		String sql_ = "select distinct t.ad_process_id from ad_process t \n "+ 
					  "where (lower(t.value) like lower('GenerateMaterialAid%') or lower(t.name) like lower('GenerateMaterialAid%')) "+ 
				      "and t.isactive='Y'";
		try
		{
			pstmt = DB.prepareStatement(sql_, null);
			rs = pstmt.executeQuery();
			if (rs.next())
				AD_Process_ID = rs.getInt(1);
		}
		catch (SQLException e)
		{
			log.log(Level.SEVERE, "product", e);
		}
		finally
		{
			DB.close(rs, pstmt);
			rs = null; pstmt = null;
		}
	}	

	public String completeIt() {
		getAD_Process_ID();
		
		if(AD_Process_ID != 0){
			//  Prepare Process
			ProcessInfo pi = new ProcessInfo ("The printing process of ", AD_Process_ID);
			pi.setAD_User_ID (Env.getAD_User_ID(Env.getCtx()));
			pi.setAD_Client_ID(Env.getAD_Client_ID(Env.getCtx()));
			pi.setRecord_ID(get_ID());

			List<ProcessInfoParameter> po = new ArrayList<ProcessInfoParameter>();
			po.add(new ProcessInfoParameter("CloseTax","Y",null,"",""));
			//
			ProcessInfoParameter[] pp = new ProcessInfoParameter[po.size()];
			po.toArray(pp);
			pi.setParameter(pp);
			//	Execute Process
			ProcessParameterPanel pu = new ProcessParameterPanel(0, pi);
			ProcessCtl.process(this, 0, (IProcessParameter) pu, pi, null);
		}
		
		//	Re-Check
		if (!m_justPrepared)
		{
			String status = prepareIt();
			if (!DocAction.STATUS_InProgress.equals(status))
				return status;
		}

		m_processMsg = ModelValidationEngine.get().fireDocValidate(this, ModelValidator.TIMING_BEFORE_COMPLETE);
		if (m_processMsg != null)
			return DocAction.STATUS_Invalid;
//
//		//	Implicit Approval
		if (!isApproved())
			approveIt();
		log.info(toString());
		
		StringBuffer info = new StringBuffer();
		
		m_processMsg = info.toString().trim();
		setProcessed(true);
//		save();
		setDocAction(DOCACTION_Close);
		return DocAction.STATUS_Completed;
	} // complitIt

	@Override
	public boolean voidIt() {
		setProcessed(true);
//		setDocAction(DOCACTION_None);
		return true;
	}

	@Override
	public boolean closeIt() {
		
		log.info(toString());
		// Before Close
		m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_BEFORE_CLOSE);
		if (m_processMsg != null)
			return false;

		setProcessed(true);
		setDocAction(DOCACTION_None);

		// After Close
		m_processMsg = ModelValidationEngine.get().fireDocValidate(this,ModelValidator.TIMING_AFTER_CLOSE);
		if (m_processMsg != null)
			return false;
		return true;
	}

	@Override
	public boolean reverseCorrectIt() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean reverseAccrualIt() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean reActivateIt() {
		setDocStatus(STATUS_Drafted);
		setDocAction(DOCACTION_Complete);
		setProcessed(false);
		setPosted(false);
		return true;
	}

	@Override
	public String getSummary() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getDocumentInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public File createPDF() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getProcessMsg() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getDoc_User_ID() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public BigDecimal getApprovalAmt() {
		// TODO Auto-generated method stub
		return null;
	}/// end DocAction

	@Override
	public void lockUI(ProcessInfo pi) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void unlockUI(ProcessInfo pi) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean isUILocked() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void executeASync(ProcessInfo pi) {
		// TODO Auto-generated method stub
		
	}
	
	public static Mhrmbonus get (Properties ctx, int hrm_bonus_ID)
	{
		Integer key = new Integer (hrm_bonus_ID);
		Mhrmbonus retValue = (Mhrmbonus) s_cache.get (key);
		if (retValue != null)
			return retValue;
		retValue = new Mhrmbonus (ctx, hrm_bonus_ID, null);
		if (retValue.get_ID () != 0)
			s_cache.put (key, retValue);
		return retValue;
	} //	get

	/**	Cache						*/
	private static CCache<Integer,Mhrmbonus>	s_cache	= new CCache<Integer,Mhrmbonus>("hrm_bonus", 20, 2);	//	2 minutes


	public static String getDocAction(Properties ctx, int hrm_bonus_ID){
	
		if(hrm_bonus_ID == 0)
			return null;
				
		String result = "";
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		// Employee data from the card
		String sql_ = "SELECT DOCACTION FROM HRM_BONUS \n" +
						"WHERE ISACTIVE='Y' \n" +
						"AND AD_CLIENT_ID="  + Env.getAD_Client_ID(ctx) + " \n" +
						"AND HRM_BONUS_ID=" + hrm_bonus_ID + " \n"; 
		try
		{
			pstmt = DB.prepareStatement(sql_,null);
			rs = pstmt.executeQuery();
			if(rs.next())
				return rs.getString(1);		
		}
		catch (SQLException e)
		{
			s_log.log(Level.SEVERE, "product", e);
		}
		finally
		{
			DB.close(rs, pstmt);
			rs = null; pstmt = null;
		}
	
		return result;
	}
}
